/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.db.jpa;

import com.db.jpa.exceptions.IllegalOrphanException;
import com.db.jpa.exceptions.NonexistentEntityException;
import db.Word;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import db.Results;
import java.util.ArrayList;
import java.util.Collection;

/**
 *
 * @author devashish
 */
public class WordJpaController {

    public WordJpaController() {
        emf = Persistence.createEntityManagerFactory("ExplorePU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Word word) {
        if (word.getResultsCollection() == null) {
            word.setResultsCollection(new ArrayList<Results>());
        }
        if (word.getResultsCollection1() == null) {
            word.setResultsCollection1(new ArrayList<Results>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Collection<Results> attachedResultsCollection = new ArrayList<Results>();
            for (Results resultsCollectionResultsToAttach : word.getResultsCollection()) {
                resultsCollectionResultsToAttach = em.getReference(resultsCollectionResultsToAttach.getClass(), resultsCollectionResultsToAttach.getResultsPK());
                attachedResultsCollection.add(resultsCollectionResultsToAttach);
            }
            word.setResultsCollection(attachedResultsCollection);
            Collection<Results> attachedResultsCollection1 = new ArrayList<Results>();
            for (Results resultsCollection1ResultsToAttach : word.getResultsCollection1()) {
                resultsCollection1ResultsToAttach = em.getReference(resultsCollection1ResultsToAttach.getClass(), resultsCollection1ResultsToAttach.getResultsPK());
                attachedResultsCollection1.add(resultsCollection1ResultsToAttach);
            }
            word.setResultsCollection1(attachedResultsCollection1);
            em.persist(word);
            for (Results resultsCollectionResults : word.getResultsCollection()) {
                Word oldWordOfResultsCollectionResults = resultsCollectionResults.getWord();
                resultsCollectionResults.setWord(word);
                resultsCollectionResults = em.merge(resultsCollectionResults);
                if (oldWordOfResultsCollectionResults != null) {
                    oldWordOfResultsCollectionResults.getResultsCollection().remove(resultsCollectionResults);
                    oldWordOfResultsCollectionResults = em.merge(oldWordOfResultsCollectionResults);
                }
            }
            for (Results resultsCollection1Results : word.getResultsCollection1()) {
                Word oldWord1OfResultsCollection1Results = resultsCollection1Results.getWord1();
                resultsCollection1Results.setWord1(word);
                resultsCollection1Results = em.merge(resultsCollection1Results);
                if (oldWord1OfResultsCollection1Results != null) {
                    oldWord1OfResultsCollection1Results.getResultsCollection1().remove(resultsCollection1Results);
                    oldWord1OfResultsCollection1Results = em.merge(oldWord1OfResultsCollection1Results);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Word word) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Word persistentWord = em.find(Word.class, word.getWordId());
            Collection<Results> resultsCollectionOld = persistentWord.getResultsCollection();
            Collection<Results> resultsCollectionNew = word.getResultsCollection();
            Collection<Results> resultsCollection1Old = persistentWord.getResultsCollection1();
            Collection<Results> resultsCollection1New = word.getResultsCollection1();
            List<String> illegalOrphanMessages = null;
            for (Results resultsCollectionOldResults : resultsCollectionOld) {
                if (!resultsCollectionNew.contains(resultsCollectionOldResults)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Results " + resultsCollectionOldResults + " since its word field is not nullable.");
                }
            }
            for (Results resultsCollection1OldResults : resultsCollection1Old) {
                if (!resultsCollection1New.contains(resultsCollection1OldResults)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Results " + resultsCollection1OldResults + " since its word1 field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Collection<Results> attachedResultsCollectionNew = new ArrayList<Results>();
            for (Results resultsCollectionNewResultsToAttach : resultsCollectionNew) {
                resultsCollectionNewResultsToAttach = em.getReference(resultsCollectionNewResultsToAttach.getClass(), resultsCollectionNewResultsToAttach.getResultsPK());
                attachedResultsCollectionNew.add(resultsCollectionNewResultsToAttach);
            }
            resultsCollectionNew = attachedResultsCollectionNew;
            word.setResultsCollection(resultsCollectionNew);
            Collection<Results> attachedResultsCollection1New = new ArrayList<Results>();
            for (Results resultsCollection1NewResultsToAttach : resultsCollection1New) {
                resultsCollection1NewResultsToAttach = em.getReference(resultsCollection1NewResultsToAttach.getClass(), resultsCollection1NewResultsToAttach.getResultsPK());
                attachedResultsCollection1New.add(resultsCollection1NewResultsToAttach);
            }
            resultsCollection1New = attachedResultsCollection1New;
            word.setResultsCollection1(resultsCollection1New);
            word = em.merge(word);
            for (Results resultsCollectionNewResults : resultsCollectionNew) {
                if (!resultsCollectionOld.contains(resultsCollectionNewResults)) {
                    Word oldWordOfResultsCollectionNewResults = resultsCollectionNewResults.getWord();
                    resultsCollectionNewResults.setWord(word);
                    resultsCollectionNewResults = em.merge(resultsCollectionNewResults);
                    if (oldWordOfResultsCollectionNewResults != null && !oldWordOfResultsCollectionNewResults.equals(word)) {
                        oldWordOfResultsCollectionNewResults.getResultsCollection().remove(resultsCollectionNewResults);
                        oldWordOfResultsCollectionNewResults = em.merge(oldWordOfResultsCollectionNewResults);
                    }
                }
            }
            for (Results resultsCollection1NewResults : resultsCollection1New) {
                if (!resultsCollection1Old.contains(resultsCollection1NewResults)) {
                    Word oldWord1OfResultsCollection1NewResults = resultsCollection1NewResults.getWord1();
                    resultsCollection1NewResults.setWord1(word);
                    resultsCollection1NewResults = em.merge(resultsCollection1NewResults);
                    if (oldWord1OfResultsCollection1NewResults != null && !oldWord1OfResultsCollection1NewResults.equals(word)) {
                        oldWord1OfResultsCollection1NewResults.getResultsCollection1().remove(resultsCollection1NewResults);
                        oldWord1OfResultsCollection1NewResults = em.merge(oldWord1OfResultsCollection1NewResults);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Long id = word.getWordId();
                if (findWord(id) == null) {
                    throw new NonexistentEntityException("The word with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Long id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Word word;
            try {
                word = em.getReference(Word.class, id);
                word.getWordId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The word with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Results> resultsCollectionOrphanCheck = word.getResultsCollection();
            for (Results resultsCollectionOrphanCheckResults : resultsCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Word (" + word + ") cannot be destroyed since the Results " + resultsCollectionOrphanCheckResults + " in its resultsCollection field has a non-nullable word field.");
            }
            Collection<Results> resultsCollection1OrphanCheck = word.getResultsCollection1();
            for (Results resultsCollection1OrphanCheckResults : resultsCollection1OrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Word (" + word + ") cannot be destroyed since the Results " + resultsCollection1OrphanCheckResults + " in its resultsCollection1 field has a non-nullable word1 field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(word);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Word> findWordEntities() {
        return findWordEntities(true, -1, -1);
    }

    public List<Word> findWordEntities(int maxResults, int firstResult) {
        return findWordEntities(false, maxResults, firstResult);
    }

    private List<Word> findWordEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Word as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Word findWord(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Word.class, id);
        } finally {
            em.close();
        }
    }

    public int getWordCount() {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select count(o) from Word as o");
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
